package com.yunji.order.business;

import com.alibaba.fastjson2.JSONObject;
import com.yunji.common.utils.bean.BeanUtils;
import com.yunji.order.bo.PayableBO;
import com.yunji.order.business.remote.WechatDelivered;
import com.yunji.order.business.remote.WechatPayable;
import com.yunji.order.domain.OrderDO;
import com.yunji.order.wechat.WechatCallbackDTO;
import com.yunji.order.emuns.PayState;
import com.yunji.order.emuns.RemoteTypes;
import com.yunji.order.service.RequestService;
import com.yunji.order.wechat.WechatRefund;
import com.yunji.order.wechat.WechatTrade;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;


/**
 * @Project: yunji-coffee
 * @Package: com.yunji.order.business
 * @Title: WechatBusiness
 * @Description: 微信业务处理
 * <p>
 * History:
 * Date                     Version     Author          Summary
 * ============================================================
 * 2024-04-11 18:09:27      V1.0        HuaAo       新建类
 */
@Slf4j
@Component
public class WechatBusiness {
    @Resource
    WechatPayable wechatPayable;
    @Resource
    WechatDelivered wechatDelivered;
    @Resource
    RequestService requestService;

    public static final String SUCCESS = "SUCCESS";
    public static final String FAIL = "FAIL";
    public static final String PROCESSING = "PROCESSING";

    public static Map<String, Object> buildSuccess() {
        Map<String, Object> result = new HashMap<>();
        result.put("code", SUCCESS);
        return result;
    }

    public static Map<String, Object> buildFail() {
        Map<String, Object> result = new HashMap<>();
        result.put("code", FAIL);
        return result;
    }

    public static Long multiply100(BigDecimal amt){
        return amt.multiply(new BigDecimal("100")).longValue();
    }

    /**
     * @return String 回调内容
     * @Title checkSign
     * @Desc 解析回调信息, 并验证签名
     * @Date 2024-04-17 17:20:11
     */
    private String checkSign(HttpServletRequest request) throws IOException {
        StringBuilder content = new StringBuilder();
        content.append(request.getHeader("Wechatpay-Timestamp")).append("\n");
        content.append(request.getHeader("Wechatpay-Nonce")).append("\n");
        BufferedReader read = request.getReader();
        StringBuilder build = new StringBuilder();
        String line;
        while ((line = read.readLine()) != null) {
            build.append(line);
        }
        log.info("【微信回调】收到回调{}", build);
        content.append(build).append("\n");
        String serial = request.getHeader("Wechatpay-Serial");
        String signature = request.getHeader("Wechatpay-Signature");
        String result = content.toString();
        log.info("【微信回调】==>验签内容{},序列方式{},签名信息{}", result, serial, signature);
        Assert.isTrue(wechatPayable.signVerify(serial, result, signature), "验签失败");
        return build.toString();
    }

    /**
     * @return Map<String, Object>
     * @Title payable
     * @Desc 微信交易回调处理
     * @Date 2024-04-17 18:27:31
     */
    public WechatCallbackDTO payCallback(HttpServletRequest request) {
        JSONObject json;
        try {
            String content = wechatPayable.decryptTrade(checkSign(request));
            json = JSONObject.parse(content);
            requestService.updateRequest(json.getString("out_trade_no"), RemoteTypes.WECHAT_JSAPI_PAYABLE.getCode(), json.getString("trade_state"), content);
            Assert.isTrue(BeanUtils.isNotNull(json), "解析失败");
            String wechatState = json.getString("trade_state");
            String wechatContent = PayState.get(wechatState);
            log.info("【微信支付回调】回调状态{}:{},json:{}", wechatState, wechatContent, json);
            Assert.isTrue(PayState.SUCCESS.getCode().equals(wechatState), "微信支付回调结果失败");
        } catch (Exception e) {
            log.error("【微信支付回调】回调解析失败{}", e.getMessage(), e);
            return new WechatCallbackDTO(false);
        }
        return new WechatCallbackDTO(true, json.getString("out_trade_no"),
                json.getString("transaction_id"),
                json.getString("success_time"));
    }

    /**
     * @return Map<String, Object>
     * @Title refund
     * @Desc 微信退款回调处理
     * @Date 2024-04-17 18:27:00
     */
    public WechatCallbackDTO refundCallback(HttpServletRequest request) {
        JSONObject json;
        try {
            String content = wechatPayable.decryptTrade(checkSign(request));
            json = JSONObject.parse(content);
            requestService.updateRequest(json.getString("out_refund_no"), RemoteTypes.WECHAT_TRADE_REFUND.getCode(), json.getString("refund_status"), content);
            Assert.isTrue(BeanUtils.isNotNull(json), "解析失败");
            String wechatState = json.getString("refund_status");
            String wechatContent = PayState.get(wechatState);
            log.info("【微信退款回调】回调状态{}:{},json:{}", wechatState, wechatContent, json);
            Assert.isTrue(PayState.SUCCESS.getCode().equals(wechatState), "微信退款回调结果失败");
        } catch (Exception e) {
            log.error("【退款回调】回调解析失败{}", e.getMessage(), e);
            return new WechatCallbackDTO(false);
        }
        return new WechatCallbackDTO(true, json.getString("out_refund_no"),
                json.getString("refund_id"),
                json.getString("success_time"));
    }

    /**
     * @return Map<String, Object>
     * @Title payout
     * @Desc 用户转账业务处理
     * @Date 2024-04-22 14:23:08.511
     */
//    public Map<String, Object> payout(HttpServletRequest request) {
//        Map<String, Object> result = new HashMap<>();
//        result.put("code", "FAIL");
//        JSONObject json = null;
//        boolean flag = false;
//        try {
//            String content = wechatPayable.decryptTrade(checkSign(request));
//            log.info("【微信转账回调】解析信息{}", content);
//            json = JSONObject.parse(content);
//            log.info("【微信转账回调】回调解密结果-{}", json);
//            Assert.isTrue(BeanUtils.isNotNull(json), "解析失败");
//            String wechatState = json.getString("payout_status");
//            String wechatContent = PayState.get(wechatState);
//            log.info("【微信转账回调】回调状态{}:{}", wechatState, wechatContent);
//            Assert.isTrue(PayState.SUCCESS.getCode().equals(wechatState), "微信转账回调结果失败");
//            flag = true;
//        } catch (Exception e) {
//            log.info("【微信转账回调】回调解析失败{}", result, e);
//        }
//        if (!flag) {
//            return result;
//        }
//        log.info("【微信转账回调】=========业务处理开始=========");
//        try {
//            String payCode = json.getString("refund_id");
//            String payoutCode = json.getString("out_trade_no");
//            log.info("【微信转账回调】交易流水号:{},支付流水号{}", payoutCode, payCode);
//            PayoutDO payout = payoutBusiness.selectPayout(payoutCode);
//            log.info("【微信转账回调】微信转账信息:{}", payout);
//            if (BeanUtils.isNull(payout)) {
//                return result;
//            }
//            payoutBusiness.callback(payout);
//            log.info("【微信转账回调】=========业务处理完成=========");
//            result.put("code", SUCCESS);
//        } catch (Exception e) {
//            log.info("【微信转账回调】回调处理失败{}", result, e);
//        }
//        return result;
//    }
    public void wechatLogistics(OrderDO order) {
        wechatDelivered.wechatLogistics(order);
    }

    public WechatTrade createTrade(PayableBO wechat) throws Exception{
        return wechatPayable.createTrade(wechat);
    }

    public WechatRefund tradeRefund(PayableBO payable) {
        return wechatPayable.tradeRefund(payable);
    }
}

